package com.taokatao.cardmee.business;

import android.app.Activity;
import android.app.Dialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.graphics.Color;
import android.graphics.drawable.ColorDrawable;
import android.os.Environment;
import android.support.annotation.NonNull;
import android.support.annotation.UiThread;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.helper.ItemTouchHelper;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;

import com.bumptech.glide.Glide;
import com.google.gson.reflect.TypeToken;
import com.makeramen.roundedimageview.RoundedImageView;
import com.taokatao.cardmee.App;
import com.taokatao.cardmee.BusEvent;
import com.taokatao.cardmee.C;
import com.taokatao.cardmee.R;
import com.taokatao.cardmee.Utils;
import com.taokatao.cardmee.api.ApiManager;
import com.taokatao.cardmee.api.RespInfo;
import com.taokatao.cardmee.api.RespWrapper;
import com.taokatao.cardmee.api.SubscriberAdapter;
import com.taokatao.cardmee.api.model.CardShareInfo;
import com.taokatao.cardmee.business.cardcode.CardCodeActivity;
import com.taokatao.cardmee.business.cardcrud.CardSearchActivity;
import com.taokatao.cardmee.business.carddetail.CardDetailActivity;
import com.taokatao.cardmee.business.login.LoginActivity;
import com.taokatao.cardmee.common.widget.AlertEditDialog;
import com.taokatao.cardmee.common.widget.ShareDialog;
import com.taokatao.cardmee.common.widget.TitleLayout;
import com.taokatao.cardmee.common.widget.recycler.helper.ItemTouchHelperAdapter;
import com.taokatao.cardmee.common.widget.recycler.helper.ItemTouchHelperViewHolder;
import com.taokatao.cardmee.common.widget.recycler.helper.OnStartDragListener;
import com.taokatao.cardmee.common.widget.recycler.helper.SimpleItemTouchHelperCallback;
import com.taokatao.cardmee.db.CardDao;
import com.taokatao.cardmee.db.model.Card;
import com.taokatao.cardmee.db.model.User;
import com.taokatao.cardmee.util.PtrHeaderHelper;
import com.umeng.socialize.ShareAction;
import com.umeng.socialize.UMShareListener;
import com.umeng.socialize.bean.SHARE_MEDIA;
import com.umeng.socialize.media.UMImage;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import butterknife.BindView;
import butterknife.ButterKnife;
import butterknife.OnClick;
import butterknife.OnLongClick;
import de.greenrobot.event.EventBus;
import in.srain.cube.views.ptr.PtrDefaultHandler;
import in.srain.cube.views.ptr.PtrFrameLayout;
import in.srain.cube.views.ptr.PtrHandler;
import jp.wasabeef.recyclerview.animators.SlideInRightAnimator;

public class CardLayout extends LinearLayout implements OnClickListener, TitleLayout.Callback, TitleLayout.Callback2, ProfileLayout.Callback
        , OnStartDragListener, ItemTouchHelperViewHolder {
    @BindView(R.id.l_title) TitleLayout lTitle;
    @BindView(R.id.l_card_guide) CardGuideLayout lCardGuide;
    @BindView(R.id.l_ptr_frame) PtrFrameLayout layPtrFrame;
    @BindView(R.id.v_recycler) RecyclerView vRecycler;

    boolean isSortByTxt;
    boolean isDragMode;
    ItemTouchHelper mItemTouchHelper;
    CardAdapter adapter;
    private Callback callback;

    Map<Long, Integer> myCardSortMap;

    public CardLayout(Context context, AttributeSet attrs) {
        super(context, attrs);
        ButterKnife.bind(this, LayoutInflater.from(context).inflate(R.layout.layout_card, this));
        setOnClickListener(this);
        lTitle.setCallback(this);
        lTitle.setCallback2(this);
    }

    public void setCallback(Callback cb) {
        callback = cb;
    }

    @Override
    public void onClick(View v) {
    }

    @Override
    public void onBackClick(TitleLayout lTitle) {
        if (App.i().getCurrUser() == null || TextUtils.isEmpty(App.i().getCurrUser().getUserTel())) {
            Intent intent = new Intent(getContext(), LoginActivity.class);
            getContext().startActivity(intent);
        } else {
            Intent intent = new Intent(getContext(), CommonScanActivity.class);
            getContext().startActivity(intent);
        }
    }

    @Override
    public void onMenuClick(TitleLayout lTitle, String flag) {
        if (App.i().getCurrUser() == null) {
            Intent intent = new Intent(getContext(), LoginActivity.class);
            getContext().startActivity(intent);
        } else {
            Utils.onMobEvent(getContext(), "clickAddCardOfMain");
            Intent intent = new Intent(getContext(), CardSearchActivity.class);
            getContext().startActivity(intent);
        }
    }

    @Override
    protected void onFinishInflate() {
        super.onFinishInflate();

        if (isInEditMode()) return;

        View.OnTouchListener swipeTouchListener = new View.OnTouchListener() {
            private boolean isInterrupt = false;

            @Override
            public boolean onTouch(View v, MotionEvent event) {
                if (!isInterrupt) {
                    if (adapter.layOpenedSwipeItemList.size() > 0) {
                        for (SwipeItemLayout last : adapter.layOpenedSwipeItemList) {
                            if (last.isMenuOpened() && !last.isInAnimation()) {
                                last.animRestore(false);
                                isInterrupt = true;
                            }
                            if (last.isInAnimation()) {
                                isInterrupt = true;
                            }
                        }
                        adapter.layOpenedSwipeItemList.clear();
                    }
                }
                switch (event.getAction()) {
                    case MotionEvent.ACTION_CANCEL:
                    case MotionEvent.ACTION_UP:
                        final boolean mTouchResult = isInterrupt;
                        isInterrupt = false;
                        return mTouchResult;
                }
                return isInterrupt;
            }
        };
        vRecycler.setOnTouchListener(swipeTouchListener);
        layPtrFrame.setOnTouchListener(swipeTouchListener);

        PtrHeaderHelper.initDefault(getContext(), layPtrFrame);
        layPtrFrame.setPtrHandler(new PtrHandler() {
            @Override
            public boolean checkCanDoRefresh(PtrFrameLayout frame, View content, View header) {
                return !isDragMode && PtrDefaultHandler.checkContentCanBePulledDown(frame, vRecycler, header);
            }

            @Override
            public void onRefreshBegin(final PtrFrameLayout frame) {
                // wait for SwipeItem close, avoid ui cache in list bug
                layPtrFrame.postDelayed(new Runnable() {
                    @Override
                    public void run() {
                        requestMyCard(true);
                    }
                }, C.settings.ANIMATION_TIME);
            }
        });
        vRecycler.setLayoutManager(new LinearLayoutManager(vRecycler.getContext()));
        vRecycler.setItemAnimator(new SlideInRightAnimator());
        vRecycler.setHasFixedSize(true);
        vRecycler.setAdapter(adapter = new CardAdapter(this, this));
        ItemTouchHelper.Callback touchHelperCallback = new SimpleItemTouchHelperCallback(adapter) {
            @Override
            public boolean isItemViewSwipeEnabled() {
                return false;
            }
        };
        mItemTouchHelper = new ItemTouchHelper(touchHelperCallback);
        mItemTouchHelper.attachToRecyclerView(vRecycler);

        if (App.i().getCurrUser() == null) {
            requestRegister();
        } else {
            prepareDataByDBQuery(null);
            requestMyCard();
        }
    }

    @Override
    public void onStartDrag(RecyclerView.ViewHolder viewHolder) {
        mItemTouchHelper.startDrag(viewHolder);
    }

    @Override
    public void onItemSelected() {
        isDragMode = true;
    }

    @Override
    public void onItemClear() {
        isDragMode = false;
    }

    private void requestMyCard() {
        requestMyCard(false);
    }

    private void requestMyCard(boolean errorToast) {
        if (App.i().getCurrUser() != null) {
            ApiManager.i().queryMyCard(getContext(), App.i().getCurrUser().getUuid(), new SubscriberAdapter<RespWrapper<List<Card>>>() {
                @Override
                public void onNext(RespWrapper<List<Card>> o) {
                    super.onNext(o);
                    if (o.code == C.http.RESULT_CODE_SUCCESS) {
                        List<Card> remoteCardList = o.decode(new TypeToken<List<Card>>() {
                        }.getType());
                        // Utils.showToast("服务器返回了" + (remoteCardList != null ? remoteCardList.size() : 0) + "条数据");
                        prepareDataByDBQuery(remoteCardList);
                    }
                }
            }.errorToast(errorToast).pullToRefresh(layPtrFrame));
        }
    }

    private void prepareDataByDBQuery(List<Card> remoteCardList) {
        Utils.logd("card layout prepareDataByDBQuery ~ remoteCardList " + (remoteCardList != null ? "[" + remoteCardList.size() + "]" : "null"));
        if (App.i().getCurrUser() != null) {
            CardDao cardDao = App.i().getUserDBSession().getCardDao();
            List<Card> localCardList = cardDao.queryBuilder().orderDesc(CardDao.Properties.AppScanTime)
                    .list();

            boolean emptyDatabase = false;

            int mySort = 0; // 由大到小
            if (localCardList.size() > 0) {
                Integer localMaxSort = localCardList.get(0).getAppScanTime();
                mySort = localMaxSort != null ? localMaxSort : 0;
            } else {
                emptyDatabase = true;
            }
            Utils.logd("card layout prepareDataByDBQuery ~ currMax [%d]", mySort);

            if (remoteCardList != null) {
                Iterator<Card> cardIterator = localCardList.iterator();
                while (cardIterator.hasNext()) {
                    Card c = cardIterator.next();
                    int mirrorIdx = remoteCardList.indexOf(c);
                    if (mirrorIdx == -1) {
                        //Utils.logd("card refresh remove [%s]", c.toString());
                        cardDao.delete(c);
                        cardIterator.remove();
                    } else {
                        Card mirror = remoteCardList.get(mirrorIdx);
                        // Utils.loge("card refresh update mirror [%s]", mirror.toString());
                        int cSort = c.getAppScanTime() != null ? c.getAppScanTime() : ++mySort;
                        c.setAppScanTime(cSort);
                        c.refreshProperties(mirror);
                        // Utils.logd("card refresh update [%s]", c.toString());
                        cardDao.insertOrReplace(c);
                        remoteCardList.remove(mirror);
                    }
                }
                for (int i = remoteCardList.size() - 1; i >= 0; i--) {
                    Card remote = remoteCardList.get(i);
                    remote.setAppScanTime(++mySort);
                }
                localCardList.addAll(remoteCardList);
                cardDao.insertOrReplaceInTx(remoteCardList);
            }
            // sys sort
            resort(localCardList, emptyDatabase);

            adapter.set(localCardList);
            int myCardCount = adapter.calcMyCardCount();
            int myCollectCount = adapter.calcMyCollectCount();
            Utils.postMainThreadBusEvent(BusEvent.CARD_REFRESHED, myCardCount, myCollectCount);

            if ((localCardList.size() > 0)) {
                lCardGuide.setVisibility(View.GONE);
                lTitle.setMenuIcon(R.mipmap.card_add);
                if (callback != null) callback.onPrepareDataCompleted();
            } else {
                lCardGuide.setVisibility(View.VISIBLE);
                lTitle.setMenuIcon(R.mipmap.card_add_2);
            }
        } else {
            lTitle.setMenuIcon(R.mipmap.card_add);
            lCardGuide.setVisibility(View.VISIBLE);
        }
    }

    // 根据手机根目录的文本文档内容排序
    private final Comparator<Card> cardSortByTxtComparator = new Comparator<Card>() {
        @Override
        public int compare(Card lhs, Card rhs) {
            if (lhs.getSysSort() == null) return 1;
            else if (rhs.getSysSort() == null) return -1;

            return lhs.getSysSort() > rhs.getSysSort() ? -1 : 1;
        }
    };

    // 根据本地库的 sortIndex排序， 此顺序逻辑为用户主动长按排序
    private final Comparator<Card> cardSortByLocalComparator = new Comparator<Card>() {
        @Override
        public int compare(Card lhs, Card rhs) {
            if (lhs.getAppScanTime() == null) return 1;
            else if (rhs.getAppScanTime() == null) return -1;

            return lhs.getAppScanTime() > rhs.getAppScanTime() ? -1 : 1;
        }
    };

    // 1、自己的卡排前面，收藏的卡排后面 2、根据名称排序
    private final Comparator<Card> cardSortByDefaultComparator = new Comparator<Card>() {
        @Override
        public int compare(Card lhs, Card rhs) {
            if (TextUtils.isEmpty(rhs.getBusinessName())) return -1;
            if (TextUtils.isEmpty(lhs.getBusinessName())) return 1;
            boolean sortByName = lhs.getBusinessName().charAt(0) <= rhs.getBusinessName().charAt(0);

            if (!TextUtils.equals(Card.STATUS_FAVORITE_CARD, lhs.getIsMyCard()) && TextUtils.equals(Card.STATUS_FAVORITE_CARD, rhs.getIsMyCard())) {
                return -1;
            } else if (TextUtils.equals(Card.STATUS_FAVORITE_CARD, lhs.getIsMyCard()) && !TextUtils.equals(Card.STATUS_FAVORITE_CARD, rhs.getIsMyCard())) {
                return 1;
            } else {
                return sortByName ? -1 : 1;
            }
        }
    };

    // isFirstDataList 是不是手机库里没有Card数据，本次设置为第一次排序
    private void resort(List<Card> localCardList, boolean isFirstDataList) {
        if (localCardList == null) return;

        if (myCardSortMap == null) {
            Utils.logd("CardLayout innerSort init sort map");
            boolean sdCardExist = Environment.getExternalStorageState().equals(android.os.Environment.MEDIA_MOUNTED);
            if (sdCardExist) {
                File myCardSortFile = new File(Environment.getExternalStorageDirectory(), "myCardMe.txt");
                if (myCardSortFile.exists() && myCardSortFile.canRead()) {
                    myCardSortMap = new HashMap<>();
                    FileReader fileReader = null;
                    BufferedReader bufferedReader = null;
                    try {
                        fileReader = new FileReader(myCardSortFile);
                        bufferedReader = new BufferedReader(fileReader);

                        String content;
                        while (!TextUtils.isEmpty(content = bufferedReader.readLine())) {
                            myCardSortMap.put(Long.parseLong(content.split("#")[0]), Integer.parseInt(content.split("#")[1]));
                        }
                        Utils.loge("CardLayout innerSort sort.txt init completed");
                    } catch (Exception e) {
                        e.printStackTrace();
                    } finally {
                        try {
                            if (fileReader != null) fileReader.close();
                            if (bufferedReader != null) bufferedReader.close();
                        } catch (IOException ignored) {
                        }
                    }
                } else {
                    Utils.loge("CardLayout innerSort sort.txt not exist");
                }
            }
        }

        if (myCardSortMap != null) {
            isSortByTxt = true;
            for (Card c : localCardList) {
                for (Long key : myCardSortMap.keySet()) {
                    if (c.getBusinessId() != null &&
                            c.getBusinessId().longValue() == key.longValue()) {
                        c.setSysSort(myCardSortMap.get(key));
                        Utils.logd("CardLayout innerSort c.setSysSort[%d] card ->%s", key, c);
                        break;
                    }
                }
            }
            Utils.loge("CardLayout innerSort sort list start");
            Collections.sort(localCardList, cardSortByTxtComparator);
        } else {
            isSortByTxt = false;
            Utils.loge("CardLayout localSort sort list start ("+isFirstDataList+")");

            if (isFirstDataList) {
                Collections.sort(localCardList, cardSortByDefaultComparator);
                for (int i = 0; i < localCardList.size() ; i++) {
                    Log.e("TTT", "CardLayout AAA " + localCardList.get(i).getBusinessName());
                    localCardList.get(i).setAppScanTime(localCardList.size() - i);
                }
                CardDao cardDao = App.i().getUserDBSession().getCardDao();
                cardDao.insertOrReplaceInTx(localCardList);
            } else {
                Collections.sort(localCardList, cardSortByLocalComparator);
            }
        }
    }

    public void onEventMainThread(BusEvent event) {
        if (event.type == BusEvent.TYPE_MAIN_THREAD) {
            switch (event.action) {
                case BusEvent.CARD_LIST_RETURN_TO_TOP:
                    layPtrFrame.refreshComplete();
                    vRecycler.smoothScrollToPosition(0);
                    break;
                case BusEvent.CARD_REFRESH:
                case BusEvent.USER_PROFILE_INFO_CHANGED:
                    requestMyCard();
                    break;
                case BusEvent.CARD_UPDATED:
                    Card cUpdated = (Card) event.content;
                    CardDao cardDao1 = App.i().getUserDBSession().getCardDao();
                    cardDao1.insertOrReplaceInTx(cUpdated);
                    adapter.update(cUpdated);
                    break;
                case BusEvent.CARD_ADD:
                    final Card cAdded = (Card) event.content;
                    CardDao cardDao2 = App.i().getUserDBSession().getCardDao();

                    Card localFirst = cardDao2.queryBuilder().orderDesc(CardDao.Properties.AppScanTime).limit(1)
                            .unique();
                    int mySort = 0; // 由大到小
                    if (localFirst != null) {
                        mySort = localFirst.getAppScanTime() != null ? localFirst.getAppScanTime() : 0;
                    }
                    cAdded.setAppScanTime(++mySort);

                    cardDao2.insertOrReplaceInTx(cAdded);

                    vRecycler.smoothScrollToPosition(0);
                    vRecycler.postDelayed(new Runnable() {
                        @Override
                        public void run() {
                            adapter.appendToFirst(cAdded);
                            lCardGuide.setVisibility(View.GONE);
                            int myCardCount1 = adapter.calcMyCardCount();
                            int myCollectCount1 = adapter.calcMyCollectCount();
                            Utils.postMainThreadBusEvent(BusEvent.CARD_REFRESHED, myCardCount1, myCollectCount1);
                        }
                    }, 500);
                    break;
                case BusEvent.CARD_DELETE:
                    final Card cDeleted = (Card) event.content;
                    CardDao cardDao3 = App.i().getUserDBSession().getCardDao();
                    cardDao3.deleteInTx(cDeleted);
                    vRecycler.postDelayed(new Runnable() {
                        @Override
                        public void run() {
                            adapter.delete(cDeleted);
                            int myCardCount2 = adapter.calcMyCardCount();
                            int myCollectCount2 = adapter.calcMyCollectCount();
                            Utils.postMainThreadBusEvent(BusEvent.CARD_REFRESHED, myCardCount2, myCollectCount2);
                            lCardGuide.setVisibility(adapter.getItemCount() > 0 ? View.GONE : View.VISIBLE);
                        }
                    }, 500);
                    break;
            }
        }
    }

    private void requestRegister() {
        if (App.i().getCurrUser() == null) {
            ApiManager.i().register(getContext(), new SubscriberAdapter<RespWrapper<User>>() {
                @Override
                public void onNext(RespWrapper<User> o) {
                    super.onNext(o);
                    if (o.code == C.http.RESULT_CODE_SUCCESS) {
                        User currUser = o.decode(User.class);
                        App.i().setCurrUser(currUser);
                    }
                }
            }.errorToast(false));
        }
    }

    @Override
    public int obtainMyCardCount() {
        return adapter != null ? adapter.calcMyCardCount() : 0;
    }

    @Override
    public int obtainMyCollectCount() {
        return adapter != null ? adapter.calcMyCollectCount() : 0;
    }

    public static class CardAdapter extends RecyclerView.Adapter implements ItemTouchHelperAdapter {
        private final int[] maskImageResource = new int[]{
                R.mipmap.card_mask_1, R.mipmap.card_mask_2, R.mipmap.card_mask_3,
        };
        private final String[] MENUS_MY_CARD = new String[]{"remark", "share"};
        private final String[] MENUS_COLLECT_CARD = new String[]{"share"};
        private final List<SwipeItemLayout> layOpenedSwipeItemList = new ArrayList<>();
        private final List<Card> dataList = new ArrayList<>();
        private final OnStartDragListener mDragStartListener;
        private final ItemTouchHelperViewHolder mItemDragStateListener;

        public CardAdapter(OnStartDragListener dragStartListener, ItemTouchHelperViewHolder itemDragStateListener) {
            mDragStartListener = dragStartListener;
            mItemDragStateListener = itemDragStateListener;
        }


        public int calcMyCardCount() {
            int myCardCount = 0;
            for (Card c : dataList) {
                if (TextUtils.equals(Card.STATUS_MY_CARD, c.getIsMyCard()) || TextUtils.equals(c.getIsMyCard(), Card.STATUS_XIAOFEI)) {
                    myCardCount++;
                }
            }
            return myCardCount;
        }

        public int calcMyCollectCount() {
            int myCollectCount = 0;
            for (Card c : dataList) {
                if (TextUtils.equals(Card.STATUS_FAVORITE_CARD, c.getIsMyCard())) {
                    myCollectCount++;
                }
            }
            return myCollectCount;
        }

        @UiThread
        public void set(@NonNull List<Card> cardList) {
            dataList.clear();
            dataList.addAll(cardList);

            Utils.loge("CardAdapter set cardList.size() : " + cardList.size());
            notifyDataSetChanged();
        }

        @UiThread
        public void update(@NonNull Card newCard) {
            int updatedIndex = dataList.indexOf(newCard);
            if (updatedIndex >= 0) {
                dataList.set(updatedIndex, newCard);
                notifyItemChanged(updatedIndex);
            }
        }

        @UiThread
        public void delete(@NonNull Card deletedCard) {
            int removeIndex = dataList.indexOf(deletedCard);
            if (removeIndex >= 0) {
                dataList.remove(removeIndex);
                notifyItemRemoved(removeIndex);
            }
        }

        @UiThread
        public void appendToFirst(@NonNull Card newCard) {
            dataList.add(0, newCard);
            notifyItemInserted(0);
        }

        @Override
        public void onItemDismiss(int position) {
            dataList.remove(position);
            notifyItemRemoved(position);
            Utils.loge("onItemDismiss position %d", position);
        }

        @Override
        public boolean onItemMove(int fromPosition, int toPosition) {
            Collections.swap(dataList, fromPosition, toPosition);

            CardDao cardDao = App.i().getUserDBSession().getCardDao();
            Card a = dataList.get(fromPosition);
            final int aSort = a.getAppScanTime() != null ? a.getAppScanTime() : 0;
            Card b = dataList.get(toPosition);
            final int bSort = b.getAppScanTime() != null ? b.getAppScanTime() : 0;
            a.setAppScanTime(bSort);
            b.setAppScanTime(aSort);
            cardDao.insertOrReplaceInTx(a, b);

            notifyItemMoved(fromPosition, toPosition);
            Utils.loge("onItemMove fromPosition %d #toPosition %d", fromPosition, toPosition);
            return true;
        }


        class ViewHolder extends RecyclerView.ViewHolder implements OnClickListener, OnLongClickListener, ItemTouchHelperViewHolder {
            @BindView(R.id.l_swipe_item) SwipeItemLayout laySwipeItem;
            @BindView(R.id.i_background) RoundedImageView iBackground;
            @BindView(R.id.i_mask) ImageView iMask;
            @BindView(R.id.i_logo) ImageView iLogo;
            @BindView(R.id.t_title) TextView tTitle;
            @BindView(R.id.t_subtitle) TextView tSubtitle;
            @BindView(R.id.i_code) ImageView iCode;
            @BindView(R.id.i_collect) ImageView iCollect;
            @BindView(R.id.v_detail_info) View vDetailInfo;
            @BindView(R.id.v_code_info) View vCodeInfo;
            @BindView(R.id.t_grade) TextView tGrade;

            Card c;
            boolean isCustomMode;

            int pos;

            ViewHolder(View view) {
                super(view);
                ButterKnife.bind(this, view);

                laySwipeItem.addSupportMenu("remark", "修改备注", R.drawable.selector_item_gray, new OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        Utils.onMobEvent(v.getContext(), "clickUpdateRemarksOfMain");
                        showEditDialog();
                    }
                });
                laySwipeItem.addSupportMenu("share", "分享", R.drawable.selector_item_red, new OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        Utils.onMobEvent(v.getContext(), "clickShareButtonOfMain", new String[]{"click"},
                                new String[]{c.getBusinessId() + "_" + c.getMCardId()});
                        showShareDialog();
                    }
                });
                laySwipeItem.setMyOnClickListener(null, new SwipeItemLayout.OnStateChangedListener() {
                    @Override
                    public void onStateChanged(SwipeItemLayout swipeItemLayout, boolean isMenuOpened) {
                        if (!layOpenedSwipeItemList.contains(swipeItemLayout)) {
                            layOpenedSwipeItemList.add(swipeItemLayout);
                        }
                    }

                    @Override
                    public boolean isLastSwipeClosed() {
                        if (layOpenedSwipeItemList.size() < 1) {
                            return true;
                        }
                        boolean flag = true;
                        for (SwipeItemLayout last : layOpenedSwipeItemList) {
                            if (last.isMenuOpened() && !last.isInAnimation()) {
                                last.animRestore(flag = false);
                            }
                        }
                        layOpenedSwipeItemList.clear();
                        return flag;
                    }
                });
            }

            @Override
            @OnClick({R.id.v_detail_info, R.id.v_code_info})
            public void onClick(View v) {
                if (laySwipeItem.isInAnimation()) {
                    return;
                }
                if (laySwipeItem.isMenuOpened()) {
                    laySwipeItem.animRestore(false);
                    return;
                }

                if (v == vDetailInfo) {
                    Utils.onMobEvent(v.getContext(), "clickCardOfMain");
                    Intent intent = new Intent(v.getContext(), CardDetailActivity.class);
                    intent.putExtra("extra_card", c);
                    v.getContext().startActivity(intent);
                } else if (v == vCodeInfo) {
                    Utils.onMobEvent(v.getContext(), "clickQRCodeOfMain");
                    Intent intent = new Intent(v.getContext(), CardCodeActivity.class);
                    intent.putExtra("extra_card", c);
                    v.getContext().startActivity(intent);
                }
            }

            @Override
            @OnLongClick({R.id.v_detail_info, R.id.v_code_info})
            public boolean onLongClick(View v) {
                Utils.logd("card item onLongClick");
                mDragStartListener.onStartDrag(this);
                return true;
            }

            void reset(Card card) {
                if (card == null) return;
                c = card;
                isCustomMode = C.settings.BUSINESS_OTHER_ID == c.getBusinessId();

                int styleColor = 0xFF242424;
                if (!TextUtils.isEmpty(c.getBackColor()) && c.getBackColor().length() == 7) {
                    styleColor = Color.parseColor(c.getBackColor());
                }
                boolean blackColorStyle = Utils.isDarkColorTheme(styleColor);
                if (!blackColorStyle) {
                    styleColor = 0xFF242424;
                }
                iCode.setImageResource(blackColorStyle ? R.mipmap.card_code_white : R.mipmap.card_code_black);
                iBackground.setImageDrawable(new ColorDrawable(styleColor));

                if (!TextUtils.isEmpty(c.getMCardAliasName())) {
                    tSubtitle.setVisibility(View.VISIBLE);
                    tSubtitle.setText(c.getMCardAliasName());
                } else {
                    tSubtitle.setVisibility(View.GONE);
                }

                Utils.logd("c.getGradeName() :" + c.getGradeName());
                if (!TextUtils.isEmpty(c.getGradeName()) && !TextUtils.equals("普通卡", c.getGradeName())) {
                    tGrade.setVisibility(View.VISIBLE);
                    tGrade.setText(c.getGradeName());
                } else {
                    tGrade.setVisibility(View.GONE);
                }

                iMask.setImageResource(maskImageResource[pos % maskImageResource.length]);
                iCollect.setVisibility(
                        (TextUtils.equals(c.getIsMyCard(), Card.STATUS_MY_CARD) || TextUtils.equals(c.getIsMyCard(), Card.STATUS_XIAOFEI))
                                ? View.GONE : View.VISIBLE);

                boolean isCustomMode = C.settings.BUSINESS_OTHER_ID == c.getBusinessId();
                tTitle.setText(isCustomMode ? c.getAnotherBusiness() : c.getBusinessName());
                if (!TextUtils.isEmpty(c.getSname())) {
                    tTitle.setText(c.getSname());
                }

                String cardIcon = isCustomMode ? c.getBuPic() : c.getMCardIcon();

//                if (!TextUtils.isEmpty(cardIcon)) {
                iLogo.setVisibility(View.VISIBLE);
                Glide.with(iLogo.getContext()).load(cardIcon)
                        .centerCrop()
                        .placeholder(R.mipmap.ic_launcher_s)
                        .bitmapTransform(App.i().getCropCircleTransformation())
                        .into(iLogo);
//                } else {
//                    iLogo.setVisibility(View.GONE);
//                }

                // 根据卡的属性重设菜单
                if (TextUtils.equals(c.getIsMyCard(), Card.STATUS_MY_CARD)) {
                    // 普通卡， 分店卡
                    laySwipeItem.resetMenu(MENUS_MY_CARD);
                } else {
                    // 收藏卡， 消费卡
                    laySwipeItem.resetMenu(MENUS_COLLECT_CARD);
                }
            }

            private void showEditDialog() {
                boolean isCustomMode = C.settings.BUSINESS_OTHER_ID == c.getBusinessId();
                String businessName = isCustomMode ? c.getAnotherBusiness() : c.getBusinessName();
                new AlertEditDialog.Builder(itemView.getContext())
                        .setTitle(businessName + "-修改备注")
                        .setInputHint("请输入备注")
                        .setOriginContent(c.getMCardAliasName())
                        .setMaxLength(50)
                        .setCallback(new AlertEditDialog.Callback() {
                            @Override
                            public void onCompleted(AlertEditDialog dialog, String inputContent) {
                                dialog.dismiss();
                                if (!TextUtils.equals(inputContent, c.getMCardAliasName())) {
                                    requestUpdateCard(inputContent);
                                }
                                laySwipeItem.animRestore(false);
                            }

                            @Override
                            public void onCancel(AlertEditDialog dialog) {
                                dialog.dismiss();
                                laySwipeItem.animRestore(false);
                            }
                        }).create().show();
            }

            private void requestUpdateCard(final String cardAliasName) {
                ApiManager.i().updateCard(itemView.getContext(), App.i().getCurrUser().getUuid(), c.getMCardId(),
                        cardAliasName, null, "", "", "", c.getMCardNo(), c.getAnotherBusiness(), c.getBuPic(), c.getCardUser(), c.getCardTel(),
                        new SubscriberAdapter<RespWrapper<RespInfo>>() {
                            @Override
                            public void onNext(RespWrapper<RespInfo> o) {
                                if (o.code == C.http.RESULT_CODE_SUCCESS) {
                                    c.setMCardAliasName(cardAliasName);
                                    tSubtitle.setText(cardAliasName);
                                    tSubtitle.setVisibility(TextUtils.isEmpty(cardAliasName) ? View.GONE : View.VISIBLE);
                                    laySwipeItem.animRestore(false);
                                }
                            }
                        }.showProgress(itemView.getContext()));
            }

            private void showShareDialog() {
                // 先提示 免责声明
                new com.taokatao.cardmee.common.widget.AlertDialog.Builder(itemView.getContext())
                        .setMessage("请谨慎分享会员卡，以免造成损失，是否继续分享？")
                        .setTitle("提示")
                        .setPositiveButton("继续", new DialogInterface.OnClickListener() {
                            @Override
                            public void onClick(DialogInterface dialog, int which) {
                                dialog.dismiss();
                                new ShareDialog.Builder(itemView.getContext()).setCallback(new ShareDialog.OnShareClickListener() {
                                    @Override
                                    public void onPlatformClick(Dialog dialog, SHARE_MEDIA platform) {
                                        requestObtainCardShareUrl(platform);
                                        dialog.dismiss();
                                    }
                                }).create().show();
                            }
                        })
                        .setNegativeButton("取消", new DialogInterface.OnClickListener() {
                            @Override
                            public void onClick(DialogInterface dialog, int which) {
                                dialog.dismiss();
                            }
                        }).create().show();
            }

            private void requestObtainCardShareUrl(final SHARE_MEDIA platform) {
                ApiManager.i().obtainCardShareUrl(itemView.getContext(), App.i().getCurrUser().getUuid(), c.getMCardId(), new SubscriberAdapter<RespWrapper<CardShareInfo>>() {
                    @Override
                    public void onNext(RespWrapper<CardShareInfo> o) {
                        super.onNext(o);
                        if (o.code == C.http.RESULT_CODE_SUCCESS) {
                            String mName = "我";
                            if (App.i().getCurrUser() != null && !TextUtils.isEmpty(App.i().getCurrUser().getUserName())) {
                                mName = App.i().getCurrUser().getUserName();
                            }
                            String mCardName = isCustomMode ? c.getAnotherBusiness() : c.getBusinessName();
                            String mCardGrade = "会员卡";
                            if (!TextUtils.isEmpty(c.getGradeName()) && !TextUtils.equals("普通卡", c.getGradeName())) {
                                mCardGrade = c.getGradeName();
                            }
                            String mTitle = String.format("%s分享的%s%s", mName, mCardName, mCardGrade);


                            UMImage image = null;
                            String picUrl = isCustomMode ? c.getBuPic() : c.getMCardIcon();
                            if (!TextUtils.isEmpty(picUrl)) {
                                image = new UMImage(itemView.getContext(), picUrl);
                            } else {
                                image = new UMImage(itemView.getContext(), R.mipmap.ic_launcher_s);
                            }
                            new ShareAction((Activity) itemView.getContext()).setPlatform(platform)
                                    .withText("不准外传！\n ▍▎▏▏▎▏▏▎▍")
                                    .withTitle(mTitle)
                                    .withTargetUrl(o.decode(CardShareInfo.class).shareMcardUrl)
                                    .withMedia(image)
                                    .setCallback(new UMShareListener() {
                                        @Override
                                        public void onResult(SHARE_MEDIA share_media) {
                                            Utils.onMobEvent(itemView.getContext(), "shareCardSucc", new String[]{"success"},
                                                    new String[]{c.getBusinessId() + "_" + c.getMCardId()});
                                            Utils.showToast("分享成功");
                                        }

                                        @Override
                                        public void onError(SHARE_MEDIA share_media, Throwable throwable) {
                                            Utils.onMobEvent(itemView.getContext(), "shareCardFail", new String[]{"fail"},
                                                    new String[]{c.getBusinessId() + "_" + c.getMCardId()});
                                            Utils.showToast("分享失败");
                                        }

                                        @Override
                                        public void onCancel(SHARE_MEDIA share_media) {
                                            Utils.onMobEvent(itemView.getContext(), "shareCardFail", new String[]{"fail"},
                                                    new String[]{c.getBusinessId() + "_" + c.getMCardId()});
                                            Utils.showToast("分享取消");
                                        }
                                    }).share();
                        }
                    }
                }.showProgress(itemView.getContext()));
            }

            @Override
            public void onItemSelected() {
                itemView.setAlpha(0.6f);
                mItemDragStateListener.onItemSelected();
            }

            @Override
            public void onItemClear() {
                itemView.setAlpha(1f);
                mItemDragStateListener.onItemClear();
            }
        }

        @Override
        public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
            return new ViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.recycler_card, parent, false));
        }

        @Override
        public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
            ViewHolder vh = (ViewHolder) holder;
            vh.pos = position;
            vh.reset(dataList.get(position));
        }

        @Override
        public int getItemCount() {
            return dataList.size();
        }
    }


    public interface Callback {
        void onPrepareDataCompleted();
    }


    @Override
    protected void onAttachedToWindow() {
        super.onAttachedToWindow();
        EventBus.getDefault().register(this);
    }

    @Override
    protected void onDetachedFromWindow() {
        super.onDetachedFromWindow();
        EventBus.getDefault().unregister(this);
    }
}
